"""
Redis Hash 方法封装
"""

from db_base.redis_db import modify_name_prefix
from db_base.redis_db.client import redis_client

from my_typing import *


class Hash:
    """ 哈希 """

    @staticmethod
    @modify_name_prefix
    def set(
        name: str,
        key: str,
        value: Union[bytes, float, int, str],
    ) -> int:
        """
        将哈希 name 的 key 设置为 value

        Args:
            name: 哈希键的名称
            key:  key
            value: value

        Returns:
            设置成功的数量
        """

        return redis_client.hset(name, key, value)

    @staticmethod
    @modify_name_prefix
    def set_many(
        name: str,
        mapping: dict[str, bytes | float | int | str],
    ) -> int:
        """
        将哈希 name 的值设置成 mapping 的键值对

        Args:
            name: 哈希键的名称
            mapping: 映射

        Returns:
            设置成功的数量
        """

        return redis_client.hset(name, mapping=mapping)

    @staticmethod
    @modify_name_prefix
    def get(
        name: str,
        key: str,
    ) -> StrOrNone:
        """
        获取哈希 name 中 key 的 value

        Args:
            name: 哈希键的名称
            key:  key

        Returns:
            value
        """

        return redis_client.hget(name, key)

    @staticmethod
    @modify_name_prefix
    def get_many(
        name: str,
        keys: Iterable[str],
        *args: str,
    ) -> list[StrOrNone]:
        """
        获取哈希 name 与 keys 排序相同的 value 列表

        Args:
            name: 哈希键的名称
            keys: key 的名称（多个）

        Returns:
            value 列表
        """

        return redis_client.hmget(name, list(keys), *args)

    @staticmethod
    @modify_name_prefix
    def get_all(name: str) -> DictStrStr:
        """
        获取哈希 name 中的所有键值对

        Args:
            name: 哈希键的名称

        Returns:
            所有键值对
        """

        return redis_client.hgetall(name)

    @staticmethod
    @modify_name_prefix
    def keys(name: str) -> ListStr:
        """
        获取哈希 name 的 key 列表

        Args:
            name: 哈希键的名称

        Returns:
            key 列表
        """

        return redis_client.hkeys(name)

    @staticmethod
    @modify_name_prefix
    def values(name: str) -> ListStr:
        """
        获取哈希 name 的 value 列表

        Args:
            name: 哈希键的名称

        Returns:
            value 列表
        """

        return redis_client.hvals(name)

    @staticmethod
    @modify_name_prefix
    def length(name: str) -> int:
        """
        获取哈希 name 的元素数量

        Args:
            name: 哈希键的名称

        Returns:
            元素数量
        """

        return redis_client.hlen(name)

    @staticmethod
    @modify_name_prefix
    def exists(
        name: str,
        key: str,
    ) -> bool:
        """
        判断 name 中是否存在 key

        Args:
            name: 哈希键的名称
            key: key

        Returns:
            True / False
        """

        return redis_client.hexists(name, key)

    @staticmethod
    @modify_name_prefix
    def delete(
        name: str,
        *keys: str,
    ) -> int:
        """
        删除键 name 中的 keys

        Args:
            name: 哈希键的名称
            keys: key 的名称（可以是单个，也可以是多个）

        Returns:
            删除的 Key 的数量
        """

        return redis_client.hdel(name, *keys)

    @staticmethod
    @modify_name_prefix
    def increase_int(
        name: str,
        key: str,
        amount: int = 1,
    ) -> int:
        """
        将哈希 name 中 key 的 value 增加 amount（对应的 value 必须是：整数）

        Args:
            name: 哈希键的名称
            key: key
            amount: 需要增加的数值（整数）

        Returns:
            增加后的数值
        """

        return redis_client.hincrby(name, key, amount)

    @staticmethod
    @modify_name_prefix
    def increase_float(
        name: str,
        key: str,
        amount: NumberType = 1.0,
    ) -> float:
        """
        将哈希 name 中 key 的 value 增加 amount（对应的 value 必须是：整数/浮点数/小数）

        Args:
            name: 哈希键的名称
            key: key
            amount: 需要增加的数值（整数 / 浮点数 / 小数）

        Returns:
            增加后的数值
        """

        return redis_client.hincrbyfloat(name, key, float(amount))
